package org.example.util;

import de.siegmar.fastcsv.reader.CloseableIterator;
import de.siegmar.fastcsv.reader.CsvReader;
import de.siegmar.fastcsv.reader.CsvRow;
import de.siegmar.fastcsv.reader.NamedCsvReader;
import de.siegmar.fastcsv.reader.NamedCsvRow;
import de.siegmar.fastcsv.writer.CsvWriter;
import de.siegmar.fastcsv.writer.LineDelimiter;
import org.example.csv.CSVData;

import java.io.IOException;
import java.nio.file.Path;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

public class CSVFaster2 {

    public static void write(Path path, CSVData csvData) {

        try (CsvWriter writer = CsvWriter.builder()
                .fieldSeparator('|')
                .lineDelimiter(LineDelimiter.LF)
                .build(path)) {
            writer.writeRow(csvData.getHeaders());
            for (String[] line : csvData.getLines()) {
                writer.writeRow(line);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        //Files.lines(path)
        //        .forEach(line -> System.out.println("Line from path: " + line));
    }

    private static void simple() {
        System.out.print("For-Each loop: ");
        for (final CsvRow csvRecord : CsvReader.builder().build("foo,bar")) {
            System.out.println(csvRecord.getFields());
        }
    }

    private static void forEachLambda() {
        System.out.print("Loop using forEach lambda: ");
        CsvReader.builder().build("foo,bar")
                .forEach(System.out::println);
    }

    private static void stream() {
        System.out.printf("CSV contains %d records%n",
                CsvReader.builder().build("foo,bar").stream().count());
    }

    public static CSVData read(Path path) {
        CSVData csvData = null;
        //System.out.print("Iterator loop: ");
        try {
            CsvReader csvReader = CsvReader.builder().fieldSeparator('|')
                    .build(path);

            CloseableIterator<CsvRow> iterator = csvReader.iterator();
            for (csvReader.iterator(); iterator.hasNext(); ) {

                final CsvRow csvRecord = iterator.next();
                if (csvRecord.getOriginalLineNumber() == 1L) {
                    List<String> headers = csvRecord.getFields();
                    csvData = new CSVData(headers);
                } else {
                    csvData.addLine((String[]) csvRecord.getFields().toArray());
                }
                //System.out.println("csvData header:" + csvData.getHeaders());
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return csvData;
    }

    public static CSVData read1(Path path, List<String> selectedHeaders) {
        CSVData csvData = new CSVData(selectedHeaders);
        //System.out.print("Iterator loop: ");
        try {
            CsvReader csvReader = CsvReader.builder().fieldSeparator('|')
                    .build(path);

            CloseableIterator<CsvRow> iterator = csvReader.iterator();
            //CloseableIterator<CsvRow> iterator = (CloseableIterator<CsvRow>) csvReader
            //CSVData csvData = null;
            //跳过 csv 第一行
            iterator.next();
            for (csvReader.iterator(); iterator.hasNext(); ) {

                CsvRow csvRecord = iterator.next();

                csvData.addLine((String[]) csvRecord.getFields().toArray());

                //System.out.println("csvData header:" + csvData.getHeaders());
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return csvData;
    }

    private static void advancedConfiguration(Path path) {
        //final String data = "#commented record\n'quoted ; field';second field\nnew record";
        //final String data = "name,age,like\n" +
        //        "sun,18,eat";
        final String parsedData;
        try {
            parsedData = CsvReader.builder()
                    .fieldSeparator('|')
                    .quoteCharacter('\'')
                    //.commentStrategy(CommentStrategy.SKIP)
                    //.commentCharacter('#')
                    .skipEmptyRows(true)
                    //.ignoreDifferentFieldCount(false)
                    .build(path)
                    .stream()
                    .map(csvRecord -> csvRecord.getFields().toString())
                    .collect(Collectors.joining(" || "));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        System.out.println("Parsed via advanced config: " + parsedData);
    }

    private static void file(Path path) throws IOException {
        //final Path path = Files.createTempFile("fastcsv", ".csv");
        //Files.writeString(path, "foo,bar\n", StandardCharsets.UTF_8);

        try (CsvReader csv = CsvReader.builder().build(path)) {
            csv.forEach(System.out::println);
        }
    }

    private static void header() {
        final Optional<NamedCsvRow> first = NamedCsvReader.builder()
                .build("header1,header2\nvalue1,value2")
                .stream().findFirst();

        first.ifPresent(csvRecord -> System.out.println("Header/Name based: " + csvRecord.getField("header2")));
    }

    private static void advancedConfiguration() {
        final String data = "'col a';'col b'\n'field 1';'field 2'\n'field 3';'field 4'";
        // final String parsedData = NamedCsvReader.builder()
                // .fieldSeparator(';')
                // .quoteCharacter('\'')
                // .commentCharacter('#')
                // .skipComments(false)
                // .build(data)
                // .stream()
                // .map(csvRow -> csvRow.getFields())
                // .collect(Collectors.joining(" || "));

        // System.out.println("Parsed via advanced config: " + parsedData);
    }

    public static CSVData read(Path path, List<String> selectedHeaders) {
        CSVData csvData = new CSVData(selectedHeaders);
        int n = selectedHeaders.size();
        //System.out.print("Iterator loop: ");
        try {
            List<String[]> collected = NamedCsvReader.builder().fieldSeparator('|')
                    .build(path)
                    .stream()
                    .map(csvRow -> {
                        String[] tmp = new String[n];
                        for (int i = 0; i < selectedHeaders.size(); i++) {
                            tmp[i] = csvRow.getField(selectedHeaders.get(i));
                        }
                        return tmp;
                    }).collect(Collectors.toList());
            csvData.setLines(collected);

            // CloseableIterator<CsvRow> iterator = csvReader.iterator();
            // //CloseableIterator<CsvRow> iterator = (CloseableIterator<CsvRow>) csvReader
            // //CSVData csvData = null;
            // //跳过 csv 第一行
            // iterator.next();
            // for (csvReader.iterator(); iterator.hasNext(); ) {
            //
            //     CsvRow csvRecord = iterator.next();
            //
            //     csvData.addLine((String[]) csvRecord.getFields().toArray());
            //
            //     //System.out.println("csvData header:" + csvData.getHeaders());
            // }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return csvData;
    }
}
